#include "directory.h"

#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>

using namespace std;

Directory::Directory()
{
}

bool Directory::exists(const string& dirPath)
{
  DIR* dir = opendir(dirPath.c_str());
  if (!dir)
    return false;

  closedir(dir);
  return true;
}

bool Directory::mkdir(const string& dirPath)
{
#ifdef WIN32
  int n = ::mkdir(dirPath.c_str());
#else
  int n = ::mkdir(dirPath.c_str(), 744);
#endif

  if(n == 0) // mkdir succeeded
    return true;
  else
    return false;

}

int Directory::count(const string& dirPath, int filter)
{
  DIR *dir = opendir(dirPath.c_str());
  struct dirent *dp;
  struct stat statbuf;
  int i = 0;

  if(!dir)
    return 0;

  while((dp = readdir(dir)) != NULL)
  {
    if(stat(dp->d_name, &statbuf))
    {
      if((S_ISDIR(statbuf.st_mode) && (filter & File::Directories)) ||
          (S_ISREG(statbuf.st_mode) && (filter & File::Files)))
      {
        if(dp->d_name[0] != '.' || (filter & File::ShowDotFiles))
          i++;
      }
    }
  }

  closedir(dir);
  return i;
}

bool Directory::isEmpty(const string& dirPath, int filter)
{
  return count(dirPath, filter) == 0;
}

list<string> Directory::listDir(const string& dirPath, int filter, string end)
{
  list<string> ret;
  DIR *dir = opendir(dirPath.c_str());
  struct dirent *dp;
  struct stat statbuf;

  if(!dir)
    return ret;

  while((dp = readdir(dir)) != NULL)
  {
    string name(dp->d_name);
    string tempFile(dirPath);
    tempFile += "/";
    tempFile += dp->d_name;

    int st = stat(tempFile.c_str(), &statbuf);

    if(st >= 0)
    {
      if((S_ISDIR(statbuf.st_mode) && (filter & File::Directories)) ||
          (!S_ISDIR(statbuf.st_mode) && (filter & File::Files)))
      {
        if(dp->d_name[0] != '.' || (filter & File::ShowDotFiles))
        {
          string name(dp->d_name);

          if(end=="" || name.find(end)==name.size()-end.size())
          {
            ret.push_back(name);
          }
        }
      }
    }
  }

  return ret;
}
